package io.gitee.dtdage.app.boot.starter.common.utils;

import io.gitee.dtdage.app.boot.starter.common.BaseTree;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 树形工具类
 *
 * @author WFT
 * @since 2024/4/14
 */
public class TreeUtil {

    /**
     * 私有化构造函数
     */
    private TreeUtil() {

    }


    /**
     * 以静态内部类实例化当前对象,从而达到懒汉式单例的效果
     */
    private static class Holder {
        private final static TreeUtil INSTANCE = new TreeUtil();
    }

    /**
     * 获取当前实例
     *
     * @return {@link TreeUtil}
     */
    public static TreeUtil getInstance() {
        return Holder.INSTANCE;
    }

    /**
     * 构建树形列表
     *
     * @param list   数据列表
     * @param rootId 根节点主键
     * @param <K>    {@link Serializable}
     * @param <T>    {@link BaseTree}
     * @return 树形结构的列表
     */
    public <K extends Serializable, T extends BaseTree<K, T>> List<T> execute(List<T> list, K rootId) {
        //  排序
        list.sort(Comparator.comparing(BaseTree::getSort));
        //  以Id作为Key,将列表存入Map集合中,方便后续查找
        Map<K, T> map = list.stream().collect(Collectors.toMap(T::getId, bean -> bean));
        //  构建返回值列表
        List<T> resultList = new ArrayList<>();
        list.forEach(item -> {
            //  判断是否为跟节点
            if (item.getPid().equals(rootId)) {
                resultList.add(item);
                return;
            }
            //  获取父节点
            T parent = map.get(item.getPid());
            if (null != parent) {
                //  获取父类节点的子节点列表
                List<T> children = parent.getChildren();
                if (null == children) {
                    parent.setChildren(children = new ArrayList<>());
                }
                children.add(item);
            }
        });
        return resultList;
    }

}
